package main

import (
	"fmt"
	"strconv"
	"time"
)

// main
//
//	@Description: 放入1~2000个数，计算每个数的和，放入resChannel
func main() {
	var goroutines int = 8

	//放入1~2000个数的channel
	numChannel := make(chan int, 2000)

	//存放结果的channel
	resChannel := make(chan string, 2000)

	//是否完成的channel
	exitChannel := make(chan bool, goroutines)

	//写入1~2000
	go putNum(numChannel)

	for i := 1; i <= goroutines; i++ {
		go calNum(numChannel, resChannel, exitChannel)
	}

	//[协程~匿名函数-异步]当从exitChannel取出8个结果后，就可以关闭resChannel
	//go func() {
	//	for i := 0; i < goroutines; i++ {
	//		<-exitChannel
	//	}
	//	close(resChannel)
	//	close(exitChannel)
	//}()

	////同步的方式关闭resChannel
	for i := 0; i < goroutines; i++ {
		<-exitChannel
	}
	close(resChannel)
	close(exitChannel)

	for v := range resChannel {
		fmt.Println("结果=", v)
	}
	fmt.Println("主函数退出~")

}

// putNum
//
//	@Description: 将1~2000个数放入numChannel
//	@param numChannel
func putNum(numChannel chan int) {
	//写入1~2000
	for i := 1; i <= 2000; i++ {
		numChannel <- i
		time.Sleep(time.Millisecond)
	}
	//关闭numChannel
	close(numChannel)
}

// calNum
//
//	@Description: 计算，将结果放入resChannel
//	@param numChannel
//	@param resChannel
//	@param exitChannel
func calNum(numChannel chan int, resChannel chan string, exitChannel chan bool) {

	for {
		num, ok := <-numChannel
		if !ok {
			break
		}
		sum := getSum(num)
		fmt.Println("读取到数据=", num, "计算值为=", sum, "放入resChannel")
		resChannel <- "[" + strconv.Itoa(num) + "]=" + strconv.Itoa(sum)
	}

	exitChannel <- true
}

// getSum
//
//	@Description: 计算
//	@param n
//	@return int
func getSum(n int) int {
	res := 0
	for i := 1; i <= n; i++ {
		res += i
	}
	return res
}
